package org.itstack.demo.netty.multicast.client;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.CharsetUtil;
import io.netty.util.NetUtil;

/**
 * UPD组播 Client
 * @author yuxuan
 *
 */
public class MClient {

	public static void main(String[] args) {
		System.setProperty("java.net.preferIPv4Stack", "true");// 只使用IPV4

		// 组播地址
		InetSocketAddress groupAddress = new InetSocketAddress("224.2.1.1", 9000);
		EventLoopGroup group = new NioEventLoopGroup();
		try {
			NetworkInterface ni = NetUtil.LOOPBACK_IF;
			Enumeration<InetAddress> addresses = ni.getInetAddresses();
			InetAddress localAddress = null;
			while (addresses.hasMoreElements()) {
				InetAddress address = addresses.nextElement();
				if (address instanceof Inet4Address) {
					localAddress = address;
				}
			}

			Bootstrap b = new Bootstrap();
			// 设置Channel
			b.group(group).channel(NioDatagramChannel.class)
					// 设置LocalAddress
					.localAddress(localAddress, groupAddress.getPort())
					// 设置Option 组播
					.option(ChannelOption.IP_MULTICAST_IF, ni)
					// 设置Option 重复地址
					.option(ChannelOption.SO_REUSEADDR, true)
					// 设置Handler
					.handler(new ChannelInitializer<NioDatagramChannel>() {

						@Override
						protected void initChannel(NioDatagramChannel ch) throws Exception {
							ch.pipeline().addLast(new SimpleChannelInboundHandler<DatagramPacket>() {

								@Override
								protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg)
										throws Exception {
									// 打印一句话
									System.out.println(msg.content().toString(CharsetUtil.UTF_8));
									ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("(client 发送)", CharsetUtil.UTF_8), groupAddress))
											.sync();// 发送数据
								}
							});
						}
					});

			// 获取Channel
			Channel ch = b.bind().sync().channel();
			// 往组播地址中发送数据报
			ch.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("hello world", CharsetUtil.UTF_8), groupAddress))
					.sync();// 发送数据
			ch.closeFuture().await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			group.shutdownGracefully();
		}
	}

}
